#ifndef IMAGE_PUBLISHER_H
#define IMAGE_PUBLISHER_H

#include "ros/ros.h"
#include <iostream>
#include "image_transport/image_transport.h"
#include "cv_bridge/cv_bridge.h"
#include "sensor_msgs/image_encodings.h"
#include "camera_info_manager/camera_info_manager.h"

#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "ImageCatcher.h"
#include "StreamFactory.h"

using namespace std;

typedef struct ImageTopics {
	const char *originImageTopic, *leftImageTopic, *rightImageTopic;
} ImageTopics;

class ImagePublisher {
private:
	cv::Mat origin, leftImage, rightImage;
	image_transport::ImageTransport imageTransport;
	image_transport::CameraPublisher leftPublisher, rightPublisher;
	image_transport::Publisher imagePublisher;
	cv_bridge::CvImagePtr leftImagePtr = nullptr;
	cv_bridge::CvImagePtr rightImagePtr = nullptr;
	boost::shared_ptr<camera_info_manager::CameraInfoManager> cameraInfoManager;
	sensor_msgs::CameraInfoPtr leftCameraInfoPtr, rightCameraInfoPtr;
	image_transport::Subscriber imageSubscriber;

public:
	explicit ImagePublisher(const ros::NodeHandle &nodeHandle, ImageTopics imageTopics);
	bool setNewFrame(const cv::Mat &frame);
	void split(cv::Mat &left, cv::Mat &right);
	void split();
	void publishAll(const ImageCatcher& imageCatcher);
	void republish(const char* compositeTopic);
	sensor_msgs::ImagePtr publishComposite(ImageCatcher imageCatcher);
	void publishStream(const StreamFactory &streamFactory);
	void imageCallback(const sensor_msgs::ImageConstPtr &msg);
};
#endif //IMAGE_PUBLISHER_H